package com.hifar.test.debugApi.client;

import com.alibaba.fastjson.JSON;
import com.hifar.fw.utils.lang.StringUtils;
import com.hifar.proj.sysSwitch.service.IBaseSysSwitchService;
import com.hifar.test.debugApi.dto.SyncEntrustStatusDTO;
import com.hifar.test.entrust.constant.EntrustConsts;
import com.hifar.test.entrust.pojo.HfEnvEntrust;
import com.hifar.test.entrust.service.IHfEnvEntrustService;
import com.hifar.utils.ToolKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
 * @author zhuWeiWei
 * @description 调试系统api客户端
 * @date 2025/10/30 8:45
 */
@Component
public class DebugApiClient {

    private static final Logger log = LoggerFactory.getLogger(DebugApiClient.class);

    /**
     * 调试系统配置key - 服务器地址（IP+端口）
     */
    private static final String DEBUG_SERVER_URL_KEY = "debug_server_url";

    /**
     * API路径常量（后部分）
     */
    private static final String API_PATH = "/api/busi/testTaskExecution/updateTestTaskStatus";

    @Autowired
    private IHfEnvEntrustService hfEnvEntrustService;

    @Autowired
    private IBaseSysSwitchService baseSysSwitchService;

    /**
     * 获取调试系统完整的API URL
     *
     * @return 完整的API URL
     * @throws RuntimeException 当配置不存在或获取失败时抛出
     */
    private String getDebugApiUrl() {
        try {
            // 从配置中获取服务器地址（IP+端口）
            String serverUrl = baseSysSwitchService.getSysConfigValueByKey(DEBUG_SERVER_URL_KEY);

            // 判断配置是否存在
            if (StringUtils.isEmpty(serverUrl)) {
                String errInfo = String.format("配置项[%s]不存在或为空，请先在系统配置表中配置调试系统服务器地址", DEBUG_SERVER_URL_KEY);
                log.error(errInfo);
                ToolKit.writeLog("debugApiLog", "获取API地址", 
                        String.format("配置Key: %s", DEBUG_SERVER_URL_KEY), 
                        null, 
                        errInfo, true);
                throw new RuntimeException(errInfo);
            }

            // 处理服务器地址，去除末尾的斜杠
            if (serverUrl.endsWith("/")) {
                serverUrl = serverUrl.substring(0, serverUrl.length() - 1);
            }

            // 拼接完整URL
            String fullUrl = serverUrl + API_PATH;
            log.debug("调试系统API地址: {}", fullUrl);

            return fullUrl;
        } catch (RuntimeException e) {
            // 直接向上抛出运行时异常
            throw e;
        } catch (Exception e) {
            String errInfo = String.format("获取调试系统API地址异常: %s", e.getMessage());
            log.error(errInfo, e);
            ToolKit.writeLog("debugApiLog", "获取API地址", 
                    String.format("配置Key: %s", DEBUG_SERVER_URL_KEY), 
                    null, 
                    errInfo, true);
            throw new RuntimeException(errInfo, e);
        }
    }

    /**
     * 同步委托状态到调试系统
     *
     * @param id 委托id
     * @return API调用结果
     */
    public String syncEntrustStatus(String id) {
        String info = String.format("委托ID: %s", id);

        try {
            // 1. 参数校验
            Assert.hasText(id, "委托id不能为空!");

            // 2. 查询委托数据
            HfEnvEntrust entrust = hfEnvEntrustService.getById(id);
            Assert.notNull(entrust, "委托数据不存在!");

            // 3. 判断数据来源，只有来自调试系统的委托才进行同步
            String dataSource = entrust.getDataSource();
            if (!EntrustConsts.TS_DATA_SOURCE.equals(dataSource)) {
                String result = String.format("委托数据来源[%s]不是调试系统，跳过同步", dataSource);
                log.info("委托ID: {}, 数据来源: {}, 跳过同步", id, dataSource);
                ToolKit.writeLog("debugApiLog", "同步委托状态", info, result, null, false);
                return result;
            }

            // 4. 组装请求数据
            SyncEntrustStatusDTO requestDTO = new SyncEntrustStatusDTO();
            requestDTO.setId(id);
            requestDTO.setTestStatus(entrust.getStatus());
            requestDTO.setEntrustCode(entrust.getEntrustCode());

            String requestInfo = String.format("委托ID: %s, 委托单号: %s, 委托状态: %s, 数据来源: %s, 请求数据: %s",
                    id, entrust.getEntrustCode(), entrust.getStatus(), dataSource, JSON.toJSONString(requestDTO));

            // 5. 获取API地址并调用调试系统API
            String apiUrl = getDebugApiUrl();
            String result = doPost(apiUrl, requestDTO);

            log.info("同步委托状态成功, 委托ID: {}, 响应: {}", id, result);
            ToolKit.writeLog("debugApiLog", "同步委托状态", requestInfo, result, null, false);

            return result;

        } catch (IllegalArgumentException e) {
            String errInfo = String.format("参数错误: %s", e.getMessage());
            log.error("同步委托状态失败, 参数错误: {}", e.getMessage());
            ToolKit.writeLog("debugApiLog", "同步委托状态", info, null, errInfo, true);
            throw e;
        } catch (Exception e) {
            String errInfo = String.format("异常信息: %s, 堆栈: %s", e.getMessage(), getStackTrace(e));
            log.error("同步委托状态失败, 委托ID: {}, 异常信息: {}", id, e.getMessage(), e);
            ToolKit.writeLog("debugApiLog", "同步委托状态", info, null, errInfo, true);
            throw new RuntimeException("同步委托状态失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取异常堆栈信息
     *
     * @param e 异常对象
     * @return 堆栈信息字符串
     */
    private String getStackTrace(Exception e) {
        StringBuilder sb = new StringBuilder();
        sb.append(e.toString()).append("\n");
        StackTraceElement[] trace = e.getStackTrace();
        for (int i = 0; i < Math.min(trace.length, 10); i++) {
            sb.append("\tat ").append(trace[i]).append("\n");
        }
        return sb.toString();
    }

    /**
     * 执行HTTP POST请求
     *
     * @param url 请求地址
     * @param data 请求数据
     * @return 响应结果
     */
    private String doPost(String url, SyncEntrustStatusDTO data) throws Exception {
        HttpURLConnection conn = null;
        OutputStream out = null;
        BufferedReader reader = null;

        try {
            // 创建连接
            URL apiUrl = new URL(url);
            conn = (HttpURLConnection) apiUrl.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(10000);

            // 发送请求数据
            String jsonData = JSON.toJSONString(data);
            log.debug("发送请求数据: {}", jsonData);

            out = conn.getOutputStream();
            out.write(jsonData.getBytes(StandardCharsets.UTF_8));
            out.flush();

            // 读取响应
            int responseCode = conn.getResponseCode();
            log.debug("响应状态码: {}", responseCode);

            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }

            return response.toString();

        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    log.warn("关闭输出流失败", e);
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception e) {
                    log.warn("关闭读取流失败", e);
                }
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

}
